﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;
using System.Diagnostics;
using System.Threading;


namespace AudioCoderModelNS
{
    class AudioCoderModel
    {
        public delegate void OutputHandler(string outStr);
        public event OutputHandler outputHandler;


        private string waviFilePath;
        private string aacEncFilePath;
        private string avsFilePath;
        private string outAacFilePath;

        private string waviArgs;
        private string aacEncArgs;
        public string AacEncArgs
        {
            get { return aacEncArgs; }
            set { aacEncArgs = value; }
        }

        private StreamReader waviOutRedirect;
        private StreamWriter aacEncInRedirect;

        private int audioCodeType;

        public int AudioCodeType
        {
            get { return audioCodeType; }
        }

        public AudioCoderModel(string waviPath, string aacEncPath, string avsPath, string outFilePath) {
            waviFilePath = waviPath;
            aacEncFilePath = aacEncPath;
            avsFilePath = avsPath;
            outAacFilePath = outFilePath;
        }

        private void calAudioCodeType(string aacBitRate) { 
            int bitRate = Convert.ToInt32(aacBitRate);
            if (bitRate<=32000) {
                audioCodeType = 0;
                return;
            }
            if (bitRate<=64000) {
                audioCodeType = 1;
                return;
            }
            audioCodeType = 2;
        }

        public void buildArgs(string aacBitRate, string sourceSampleRate) {
            calAudioCodeType(aacBitRate);
            if (audioCodeType == 0) {
                waviArgs = "\"" + avsFilePath + "\"" + @" - /r";
                aacEncArgs = String.Format("- \"{0}\" --br {1} --he --ps --pns --rawpcm {2} 2 16", outAacFilePath, aacBitRate, sourceSampleRate);
                return;
            }
            if (audioCodeType == 1) {
                waviArgs = "\"" + avsFilePath + "\"" + @" - /r";
                aacEncArgs = String.Format("- \"{0}\" --br {1} --he --pns --rawpcm {2} 2 16", outAacFilePath, aacBitRate, sourceSampleRate);
                return;
            }
            if (audioCodeType == 2) {
                waviArgs = "\"" + avsFilePath + "\"" + @" - /r";
                aacEncArgs = String.Format("- \"{0}\" --br {1} --lc --pns --rawpcm {2} 2 16", outAacFilePath, aacBitRate, sourceSampleRate);
                return;
            }
            
        }

        private void stardardInOutRedirect() {
            waviOutRedirect.BaseStream.CopyTo(aacEncInRedirect.BaseStream);
            aacEncInRedirect.Close();
        }

        public void startCoding() {
            ProcessStartInfo waviStart = new ProcessStartInfo();

            waviStart.FileName = waviFilePath;
            waviStart.Arguments = waviArgs;
            waviStart.UseShellExecute = false;
            waviStart.RedirectStandardOutput = true;
            waviStart.CreateNoWindow = true;

            Process waviProcess = Process.Start(waviStart);

            ProcessStartInfo aacEncStart = new ProcessStartInfo();

            aacEncStart.FileName = aacEncFilePath;
            aacEncStart.Arguments = aacEncArgs;
            aacEncStart.UseShellExecute = false;
            aacEncStart.RedirectStandardOutput = true;
            aacEncStart.RedirectStandardInput = true;
            aacEncStart.CreateNoWindow = true;

            Process aacEncProcess = Process.Start(aacEncStart);


            waviOutRedirect = waviProcess.StandardOutput;
            aacEncInRedirect = aacEncProcess.StandardInput;
            StreamReader outStr = aacEncProcess.StandardOutput;

            Thread ioRedirectTh = new Thread(new ThreadStart(stardardInOutRedirect));

            ioRedirectTh.Start();

            string result = outStr.ReadToEnd();
            //fillParametersDic(result);

            outputHandler(result);
            //Console.WriteLine(result);

            ioRedirectTh.Join();

            waviProcess.WaitForExit();
            aacEncProcess.WaitForExit();

            
        }
    }
}
